package FIT::Document::Parser;

use FIT::Class;
use IO::All -utf8;
use File::Basename;
use FIT::Util::IO;
use aliased 'FIT::Document::Parser::Sanitizer';

has in  => (is => 'ro', isa => 'ReadableFile', required => 1, coerce => 1);
has out => (is => 'ro', isa => 'Str', required => 1);

has out_dir => (
    is       => 'ro',
    isa      => 'WritableDir',
    lazy     => 1,
    default  => sub { io(dirname shift->out_file) },
);

has out_file => (
    is       => 'ro',
    isa      => 'WritableFile',
    lazy     => 1,
    default  => sub {
        # compute this from "out", which is a DWIMer for a dir or a file
        my $self = shift;
        my $out_file = $self->out =~ /\.htm(?:l?)$/?
            $self->out: $self->out. "/". basename $self->in;

        my $out_dir = io( dirname $out_file );
        die "File exists with same name as out_dir" if $out_dir->is_file;

        $out_dir->mkpath unless $out_dir->is_dir;
        $out_file = io( $out_file );
        $out_file->touch;
        return $out_file;
    },
);

has twig => (
    is       => 'ro',
    isa      => 'XML::Twig',
    lazy     => 1,
    handles  => [qw( root )],
    default  => sub {
        Sanitizer->make_twig(
            html    => $_[0]->in->all,
            out_dir => $_[0]->out_dir,
        );
    },
);

sub write {
    my $f = $self->out_file;
    $f->write( Sanitizer->twig_as_HTML( $self->twig ) );
    $f->close;
}

sub first_table { $self->root->first_table }
sub in_dir      { io(dirname $self->in) }


=head1 NAME

FIT::Document::Parser - read, parse, and write a test document


=head1 SYNOPSIS

    use aliased 'FIT::Document::Parser';

    my $parser = Parser->new(
        in  => "../eg/html/Division.html",
        out => "tmp", # can be a dir or a file with .html suffix
    );
    print $parser->first_table->fixture_name; # FIT.eg.Division
    print $parser->out_dir;                   # tmp
    print $parser->out_file;                  # tmp/Division.html
    $parser->write;


=head1 DESCRIPTION

The Parser is the entry point for the entire FIT parsing drama. you create a
parser with an input file, and either an output directory or an output file.

Then you can access the first table in the document using C< first_table() >.

After you are done modifying the twig, write it with C< write() >.

=cut

